package mt.dummy;

import static org.junit.Assert.*;
import mt.Order;
import mt.comm.implement.ServerComm;
import mt.comm.ServerSideMessage;

import java.util.ArrayList;
import java.util.HashMap;

import mt.Order;
import mt.comm.ClientComm;
import mt.comm.ServerSideMessage.Type;
import mt.server.MicroTraderServer;
import mt.server.MicroTraderServerImp;

import org.junit.Test;

public class MicroTraderServerDummyTest {


	@Test
	public void testStart() {
	}

	@Test
	public void testAddNewOrder() {
				MicroTraderServerImp microServer = new MicroTraderServerImp();
				Order nullOrder = null;
				Order validOrder = Order.createBuyOrder("Anders", "cars", 10, 10);
				microServer.addNewOrder(validOrder);
				assertTrue(microServer.getOrder_List().contains(validOrder));
				microServer.addNewOrder(nullOrder);
				assertFalse(microServer.getOrder_List().contains(nullOrder));

	}

	@Test
	public void testIsOrderValid() {
		MicroTraderServerImp microServer = new MicroTraderServerImp();
		ArrayList<Order> ORDER_LIST = new ArrayList<Order>();

//		Order order = new Order("ordem", false, "stock", 444, 9.8);  	
		Order invalidOrder1 = null;
		Order buyOrder = Order.createBuyOrder("Buyorder", "stock", 444, 9.8);
		Order buyOrder2 = Order.createBuyOrder("Buyorder", null, 444, 9.8);
		Order buyOrder3 = Order.createBuyOrder("Buyorder", "stock", -444, 9.8);
		Order buyOrder4 = Order.createBuyOrder("Buyorder", "stock", 444, -9.8);
		Order sellOrder = Order.createSellOrder("Sellorder", "stock", 444, 9.8);
		Order sellOrder2 = Order.createSellOrder("Sellorder", null, 444, 9.8);
		Order sellOrder3 = Order.createSellOrder("Sellorder", "stock", -444, 9.8);
		Order sellOrder4 = Order.createSellOrder("Sellorder", "stock", 444, -9.8);
		
//		microServer.getOrder_List().add(order);
		microServer.getOrder_List().add(invalidOrder1);
		microServer.getOrder_List().add(buyOrder);
		microServer.getOrder_List().add(buyOrder2);
		microServer.getOrder_List().add(buyOrder3);
		microServer.getOrder_List().add(buyOrder4);
		microServer.getOrder_List().add(sellOrder);
		microServer.getOrder_List().add(sellOrder2);
		microServer.getOrder_List().add(sellOrder3);
		microServer.getOrder_List().add(sellOrder4);
		
//		assertTrue(microServer.isOrderValid(order));
		assertFalse(microServer.isOrderValid(invalidOrder1));
		assertTrue(microServer.isOrderValid(buyOrder));
		assertFalse(microServer.isOrderValid(buyOrder2));
		assertFalse(microServer.isOrderValid(buyOrder3));
		assertFalse(microServer.isOrderValid(buyOrder4));
		assertTrue(microServer.isOrderValid(sellOrder));
		assertFalse(microServer.isOrderValid(sellOrder2));
		assertFalse(microServer.isOrderValid(sellOrder3));
		assertFalse(microServer.isOrderValid(sellOrder4));

	}
	@Test
	public void testOrderCompleted() {
		MicroTraderServerImp microServer = new MicroTraderServerImp();
		ServerCommDummy serverComm = new ServerCommDummy();
		serverComm.start();
		String client1 = "Anders"; 
		Order order1 = Order.createSellOrder(client1, "cars", 10, 10);
		microServer.newClientConnected(client1);
		serverComm.connectClient(client1);
		microServer.addNewOrder(order1);
		assertTrue(microServer.getOrder_List().contains(order1));


		microServer.orderCompleted(order1);
		assertFalse(microServer.getOrder_List().contains(order1));

	}

	@Test
	public void testUserDisconnected() {
		MicroTraderServerImp microServer = new MicroTraderServerImp();
		ServerCommDummy serverComm = new ServerCommDummy(); 
		String client1 = "Anders"; 
		Order order1 = Order.createSellOrder(client1, "cars", 10, 10);
		microServer.newClientConnected(client1);
		serverComm.connectClient(client1);
		microServer.addNewOrder(order1);
		assertTrue(microServer.getOrder_List().contains(order1));

		serverComm.disconnectClient(client1);
		microServer.userDisconnected(client1);
		assertFalse(microServer.getOrder_List().contains(order1));

	}

	@Test
	public void testUpdateClients() {
		MicroTraderServerImp microServer = new MicroTraderServerImp();
		ServerCommDummy serverComm = new ServerCommDummy();
		String client1 = "Anders"; 
		Order order1 = Order.createSellOrder(client1, "cars", 10, 10);
		microServer.addNewOrder(order1);
		serverComm.connectClient(client1);
		assertTrue(microServer.getOrder_List().contains(order1));

		String client2 = "Joao"; 
		Order order2 = Order.createBuyOrder(client2, "cars", 20, 10);
		microServer.addNewOrder(order2);
		serverComm.connectClient(client2);
		assertTrue(microServer.getOrder_List().contains(order2));

		Order order3 = null;
		microServer.updateClients(order3);  
		assertFalse(microServer.getOrder_List().contains(order3));
		

	}  

	@Test
	public void testNewClientConnected() {
		MicroTraderServerImp microServer = new MicroTraderServerImp();
		ServerCommDummy serverComm = new ServerCommDummy();
		String client1 = "Anders"; 
		Order order1 = Order.createSellOrder(client1, "cars", 10, 10);
		microServer.newClientConnected(client1);
		serverComm.connectClient(client1);
		microServer.addNewOrder(order1);
		assertTrue(serverComm.clientIsConnected(client1));

		microServer.newClientConnected(client1);
		assertTrue(serverComm.clientIsConnected(client1));
	}

	@Test
	public void testIsUserConnected() {
		MicroTraderServerImp microServer = new MicroTraderServerImp();
		ServerCommDummy serverComm = new ServerCommDummy();
		String user1 = "user1";
		String user2 = "user2";
		Order order = Order.createBuyOrder(user1, "something", 1, 1);
		microServer.addNewOrder(order);
//		assertTrue(microServer.isUserConnected(user1));
//		assertFalse(microServer.isUserConnected(user2));
		serverComm.start();
		String client1 = "Anders"; 
		Order order1 = Order.createSellOrder(client1, "cars", 10, 10);
		microServer.newClientConnected(client1);
		serverComm.connectClient(client1);
		microServer.addNewOrder(order1);
//		assertTrue(microServer.isUserConnected(client1));
		String client2 = "Joao";
//		assertFalse(microServer.isUserConnected(client2));

	}

	@Test
	public void testOrderBuy() {
		System.out.println("Teste orderBuy()");

		MicroTraderServerImp microServer = new MicroTraderServerImp(); 
		ServerCommDummy serverComm = new ServerCommDummy();
		//sell Order - 10 cars - 10 per unit
		String client1 = "Anders"; 
		Order order1 = Order.createSellOrder(client1, "cars", 10, 10);
		serverComm.connectClient(client1);
		microServer.addNewOrder(order1);
		assertTrue(microServer.getOrder_List().contains(order1));

		//buy Order - 10 cars - 10 per unit
		String client2 = "Joao";  
		Order order2 = Order.createBuyOrder(client2, "cars", 10, 10);
		serverComm.connectClient(client2);
		microServer.addNewOrder(order2);
		assertTrue(microServer.getOrder_List().contains(order2));
 
		//test fails because order1 is a sell order
		microServer.orderBuy(order1);
		assertTrue(microServer.getOrder_List().contains(order1));

	
	//both orders are completely succeeded
		microServer.orderBuy(order2);
		assertFalse(microServer.getOrder_List().contains(order1));
		assertFalse(microServer.getOrder_List().contains(order2)); 

		//only sell order is succeeded -> stock sellorder3 < stock buyorder4
		Order sellorder3 = Order.createSellOrder(client1, "cups", 5, 10);
		Order buyorder4 = Order.createBuyOrder(client2, "cups", 10, 10);
		microServer.addNewOrder(sellorder3);
		microServer.addNewOrder(buyorder4);
		microServer.orderBuy(buyorder4);
		
		assertFalse(microServer.getOrder_List().contains(sellorder3)); 
		assertTrue(microServer.getOrder_List().contains(buyorder4));
		
		//the next line shloud not be necessary
		microServer = new MicroTraderServerImp(); 
		 
		//only buy order is succeeded -> stock sellorder5 > stock buyorder6
		Order sellorder5 = Order.createSellOrder(client1, "computers", 10, 11);
		Order buyorder6 = Order.createBuyOrder(client2, "computers", 5, 11);
		microServer.addNewOrder(sellorder5);
		microServer.addNewOrder(buyorder6);
		microServer.orderBuy(buyorder6);
		assertTrue(microServer.getOrder_List().contains(sellorder5));
		assertFalse(microServer.getOrder_List().contains(buyorder6));
	
	}

	@Test
	public void testOrderSell() {
		System.out.println("Teste orderSell()");

		MicroTraderServerImp microServer = new MicroTraderServerImp();
		ServerCommDummy serverComm = new ServerCommDummy();


		//buy Order - 10 cars - 10 per unit
		String client2 = "Joao"; 
		Order order2 = Order.createBuyOrder(client2, "cars", 10, 10);
		serverComm.connectClient(client2);
		microServer.addNewOrder(order2);
		assertTrue(microServer.getOrder_List().contains(order2));

		//sell Order - 10 cars - 10 per unit
		String client1 = "Anders"; 
		Order order1 = Order.createSellOrder(client1, "cars", 10, 10);
		serverComm.connectClient(client1);
		microServer.addNewOrder(order1);
		assertTrue(microServer.getOrder_List().contains(order1));
		
		//test fails because order2 is a buy order
		microServer.orderSell(order2);
		assertTrue(microServer.getOrder_List().contains(order2));

		//both orders are completely succeeded
		microServer.orderSell(order1);
		assertFalse(microServer.getOrder_List().contains(order1));
		assertFalse(microServer.getOrder_List().contains(order2));

		//only sell order is succeeded -> stock sellorder3 < stock buyorder4
		Order sellorder3 = Order.createSellOrder(client1, "cups", 5, 10);
		Order buyorder4 = Order.createBuyOrder(client2, "cups", 10, 10);
		microServer.addNewOrder(sellorder3);
		System.out.println(buyorder4.getNumberOfUnits());
		microServer.addNewOrder(buyorder4);
		microServer.orderSell(sellorder3);
		
		assertFalse(microServer.getOrder_List().contains(sellorder3));
		assertTrue(microServer.getOrder_List().contains(buyorder4));
		
		microServer = new MicroTraderServerImp(); 
		
		//only buy order is succeeded -> stock sellorder5 > stockbuyorder6
		Order sellorder5 = Order.createSellOrder(client1, "computers", 10, 10);
		Order buyorder6 = Order.createBuyOrder(client2, "computers", 5, 10);
		microServer.addNewOrder(sellorder5);
		microServer.addNewOrder(buyorder6);
		microServer.orderSell(sellorder5);
		assertTrue(microServer.getOrder_List().contains(sellorder5));
		assertFalse(microServer.getOrder_List().contains(buyorder6));
	
	}

	
	//if buy and sell dont work, this cant work
	@Test
	public void testMakeTransaction() {
		MicroTraderServerImp microServer = new MicroTraderServerImp(); 
		ServerCommDummy serverComm = new ServerCommDummy();
		//serverComm.start();

		//sell Order - 10 cars - 10 per unit
		String client1 = "Anders"; 
		Order order1 = Order.createSellOrder(client1, "cars", 10, 10);
		serverComm.connectClient(client1);
		microServer.addNewOrder(order1);
		assertTrue(microServer.getOrder_List().contains(order1));

		//buy Order - 10 cars - 10 per unit
		String client2 = "Joao"; 
		Order order2 = Order.createBuyOrder(client2, "cars", 5, 10);
		serverComm.connectClient(client2);
		microServer.addNewOrder(order2);
		assertTrue(microServer.getOrder_List().contains(order2));

		Order order3 = null;
		microServer.makeTransaction(order3);
		assertTrue(microServer.getOrder_List().contains(order1));
		assertTrue(microServer.getOrder_List().contains(order2));
		assertFalse(microServer.getOrder_List().contains(order3));


		microServer.makeTransaction(order1);
		assertTrue(microServer.getOrder_List().contains(order1));
		assertFalse(microServer.getOrder_List().contains(order2));

		microServer = new MicroTraderServerImp(); 
		serverComm = new ServerCommDummy();

		order1 = Order.createSellOrder(client1, "cars", 10, 10);
		order2 = Order.createBuyOrder(client2, "cars", 5, 10);
		serverComm.connectClient(client1);
		microServer.addNewOrder(order1);
		serverComm.connectClient(client2);
		microServer.addNewOrder(order2);
		
		
		microServer.makeTransaction(order2);
		assertTrue(microServer.getOrder_List().contains(order1));
		assertFalse(microServer.getOrder_List().contains(order2));
	}

}
